package com.spsa.persistencia.dao;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.spsa.excepciones.ActualizarDatosException;
import com.spsa.excepciones.EliminarDatosException;
import com.spsa.excepciones.GuardarDatosException;
import com.spsa.excepciones.RecuperarDatosException;
import com.spsa.persistencia.entidades.Usuario;

@Stateless
public class UsuarioDao {
	static final Logger logger = LogManager.getLogger(UsuarioDao.class.getName());
	
	@PersistenceContext(unitName="Notificacion")
	private EntityManager em;
	
	public Usuario buscar(String username, String password) throws RecuperarDatosException{
		try {
			Query query = em.createQuery("SELECT u FROM Usuario u WHERE u.username = :username AND "
					+ "u.password = :password");
			query.setParameter("username", username);
			query.setParameter("password", password);
			
			return (Usuario)query.getSingleResult();
		}
		catch(NoResultException e) {
			logger.info("No se encontro el usuario en la BD. User: " + username + " Password: " + password);
			return null;
		}
		catch(Exception e) {
			logger.error("Error al buscar un usuario en la BD. User: " + username + " Password: " + password, e);
			throw new RecuperarDatosException("Erro al validar las credenciales del usuario");
		}
	}
	
	public boolean existe(String codigo) throws RecuperarDatosException{
		try {
			return em.find(Usuario.class, codigo) != null;
		}
		catch(Exception e) {
			logger.error("No se pudo encontrar el usuario con codigo: " + codigo + " en la BD", e);
			throw new RecuperarDatosException("No se pudo encontrar eo usuario con codigo: " + codigo + " en la BD");
		}
	}

	public List<Usuario> listar() throws RecuperarDatosException{
		try {
			Query query = em.createQuery("SELECT u FROM Usuario u");
			List<Usuario> usuarios = query.getResultList();
			return usuarios;
		} catch (Exception e) {
			logger.fatal("No se pudo recuperar la lista de Usuarios de la BD", e);
			throw new RecuperarDatosException("No se pudo recuperar la lista de Usuarios de la BD");
		}
	}

	public void guardar(Usuario usuario) throws GuardarDatosException {
		try {
			em.merge(usuario);
			logger.info("Se registro un Usuario: " + usuario);
		}
		catch(Exception e) {
			logger.error("No se pudo guardar un Usuario en la BD. " + usuario, e);
			throw new GuardarDatosException("No se pudo guardar un Usuario en la BD. " + usuario);
		}
	}

	public void actualizar(Usuario usuario) throws ActualizarDatosException {
		try {
			em.merge(usuario);
			logger.info("Se actualizo los datos del Usuario en la BD. " + usuario);
		}
		catch(Exception e) {
			logger.error("No se pudo actualizar los datos del Usuario en la BD. " + usuario, e);
			throw new ActualizarDatosException("No se pudo actualizar los datos del Usuario en la BD. " + usuario);
		}
	}

	public void eliminar(Usuario usuario) throws EliminarDatosException {
		try {
			usuario = em.find(Usuario.class, usuario.getCodigo());
			em.remove(usuario);
			logger.info("Se elimino un Usuario de la BD. " + usuario);
		}
		catch(Exception e) {
			logger.error("No se pudo eliminar un Usuario de la BD. " + usuario, e);
			throw new EliminarDatosException("No se pudo eliminar un Usuario de la BD. " + usuario);
		}
	}

}
